<!--首页-访问告警分布图页面-->
<template>
	<div class="app-container">
		<el-row>
			<el-col :span="12">
				<div v-loading="alarmRatioMapLoading" class="bg-chart">
					<i class="title-icon"></i>
					<div style="color: #fff; margin-top: 13px; margin-left: 40px; fontweight: bold; font-size: 18px">
						告警类型占比 ({{ dataQJStart }}-{{ dataQJEnd }})
					</div>

					<div id="alarmRatioMap" :style="{ height: topPioHeight, width: width }">
						<div><svg-icon class-name="nodata" icon-class="nodata"></svg-icon>暂无数据~</div>
					</div>
				</div>
				<div v-loading="nodeRatioMapLoading" class="bg-chart">
					<!-- <div
            style="color:#fff;  z-index: 999; width: 128px; margin-left: 155px; position: absolute;margin-top:21px"
          >( {{ dataQJStart}} -{{dataQJEnd}} )</div>-->
					<i class="title-icon"></i>

					<div id="nodeRatioMap" :style="{ height: height, width: width }"></div>
				</div>
			</el-col>

			<el-col :span="12">
				<YdCard
					v-show="ui.alarmRatioDetailShow"
					v-loading="downloadLoading"
					element-loading-text="正在下载，请稍后......"
					:title="'类型占比'"
					:enableDownload="true"
					@downloadHandler="download('type')"
				>
					<YdTable
						:formData="queryDetailsParams"
						:tableConfig="alarmRatioDetailConfig"
						:tableData="tableData.data"
						@sizeChangeHandler="queryAlarmRatioDetail"
						@currentChangeHandler="queryAlarmRatioDetail"
						@sortChangeHandler="queryAlarmRatioDetail"
					></YdTable>
				</YdCard>
				<YdCard
					v-show="ui.nodeRatioDetailShow"
					v-loading="downloadLoading"
					element-loading-text="正在下载，请稍后......"
					class="el-table-title-no"
					:title="'节点占比'"
					:enableDownload="true"
					@downloadHandler="download('node')"
				>
					<YdTable
						:formData="queryDetailsParams"
						:tableConfig="nodeRatioDetailConfig"
						:tableData="tableData.data"
						@sizeChangeHandler="queryNodeRatioDetail"
						@currentChangeHandler="queryNodeRatioDetail"
						@sortChangeHandler="queryNodeRatioDetail"
					></YdTable>
				</YdCard>
			</el-col>
		</el-row>
	</div>
</template>

<script setup name="alarmDistributeMap" lang="ts">
import { useRoute, useRouter } from 'vue-router';
import { ref, reactive, shallowReactive, getCurrentInstance, onMounted, onBeforeUnmount } from 'vue';
import * as echarts from 'echarts';
import { noDataOption } from '@/utils/chartNoData';
import { getAlarmRatioMap, getNodeRatioMap, getAlarmRatioDetail, getNodeRatioDetail, exportList } from '@/api/bpm/home/alarm_distribute_map_api';
import { downloadFromBlob, parseTime, checkDebounce } from '@/utils/common';
import { resizeMixins } from '@/mixins/resize';

const instance = getCurrentInstance();
const proxy = instance?.proxy;

const route = useRoute();
const router = useRouter();

const props = defineProps({
	topPioHeight: {
		type: String,
		default: '300px',
	},
	width: {
		type: String,
		default: '100%',
	},
	height: {
		type: String,
		default: '500px',
	},
});

const nodeRatioMapLoading = ref(false);
const alarmRatioMapLoading = ref(false);

const alarmRatioDetailConfig = reactive<TableConfigType>({
	columns: [
		{
			label: '告警类型',
			prop: 'alarmIndicatorName',
		},
		{
			label: '告警时间',
			prop: 'alarmTriggerTime',
			formatter(row: any, val: any) {
				return parseTime(val);
			},
			sortable: true,
		},
		{
			label: '告警级别',
			prop: 'alarmLevelName',
			width: 100,
		},
		{
			label: '归属节点',
			prop: 'segmentName',
		},
		{
			label: '告警信息',
			prop: 'alarmContext',
			width: 250,
		},
	],
	pagination: {
		pageNum: 1,
	},
	loading: true,
	disableOrderNumber: true,
});
const nodeRatioDetailConfig = reactive<TableConfigType>({
	columns: [
		{
			label: '告警时间',
			prop: 'alarmTriggerTime',
			formatter(row: any, val: any) {
				return parseTime(val);
			},
			sortable: true,
		},
		{
			label: '告警级别',
			prop: 'alarmLevelName',
			width: 135,
		},
		{
			label: '归属节点',
			prop: 'segmentName',
		},
		{
			label: '告警信息',
			prop: 'alarmContext',
		},
	],
	pagination: {
		pageNum: 1,
	},
	loading: true,
	disableOrderNumber: true,
});

const downloadLoading = ref(false);
const chart = shallowReactive<anyObj>({
	alarmRatioMap: null,
	nodeRatioMap: null,
});
// 遮罩层
const loading = ref(false);
// 查询参数
const queryParams = reactive<FormModelType>({
	pageNum: 1,
	pageSize: 10,
	...route.query,
});

const queryDetailsParams = reactive<FormModelType>({
	pageNum: 1,
	pageSize: 10,
});
const ui = reactive<anyObj>({});
//右侧grid结果集
const tableData = reactive({
	data: [],
});

const nodeRatioDetailTableData = reactive({
	data: [],
});
const tableType = reactive({ type: '类型占比', node: '节点占比' });
const dataQJStart = ref('');
const dataQJEnd = ref('');

const dataNull = ref(false);
const debounceObj = reactive({
	// 频率(ms)
	time: 200,
	flag: true,
});
const alarmRatioMapData = ref([]);
const AlarmRatioNum = ref<number>();
const AlarmRatioList = ref([]);

resizeMixins(chart);

onMounted(() => {
	nodeRatioDetailConfig.loading = false;
	alarmRatioDetailConfig.loading = false;
	const routeParams = route.query;
	if (!routeParams.systemId || !routeParams.currentTime) {
		return router.push({ path: '/index' });
	}
	initCharts();
});

onBeforeUnmount(() => {
	if (!chart) {
		return;
	}
	for (let map in chart) {
		chart[map].dispose();
	}
});
/**
 * 初始化图表
 */
function initCharts() {
	chart.alarmRatioMap = echarts.init(document.getElementById('alarmRatioMap') as HTMLElement);
	chart.nodeRatioMap = echarts.init(document.getElementById('nodeRatioMap') as HTMLElement);
	initQuery();
}
/**
 * 查询
 */
function initQuery() {
	toggleUi(true);
	// queryParams.currentTime = formatDate(queryParams.currentTime);
	queryAlarmRatioMap(queryParams);
}

//告警类型占比图
function queryAlarmRatioMap(params: any) {
	alarmRatioMapLoading.value = true;
	nodeRatioMapLoading.value = true;
	getAlarmRatioMap(params).then((res: ApiResponse) => {
		alarmRatioMapLoading.value = false;
		if (res.code !== 0) {
			return;
		}
		const labelTime = res.data[0];
		const data = res.data;
		const dataList = res.data[1] === undefined ? [] : res.data[1];
		AlarmRatioNum.value = res.data.length;
		AlarmRatioList.value = res.data;

		dataQJStart.value = labelTime[labelTime.length - 2];
		dataQJEnd.value = labelTime[labelTime.length - 1];
		alarmRatioMapData.value = data;

		if (AlarmRatioNum.value === 2) {
			if (dataList[dataList.length - 3] === 0) {
				dataNull.value = true;
				dataNullFuc();
			} else {
				alarmRatioMapSetOption(chart.alarmRatioMap, data, labelTime[labelTime.length - 2]);
			}
		} else {
			alarmRatioMapSetOption(chart.alarmRatioMap, data, labelTime[labelTime.length - 2]);
		}
		if (res.data.length > 1) {
			let param = res.data[1];
			Object.assign(queryDetailsParams, queryParams, param[param.length - 1]);
			queryAlarmRatioDetail();
			queryNodeRatioMap(queryDetailsParams);
		} else {
			nodeRatioMapLoading.value = false;
		}
		//告警类型占比图点击事件，通过seriesType区分line or pie
		chart.alarmRatioMap.off('click');
		chart.alarmRatioMap.on('click', function (param: anyObj) {
			toggleUi(true);
			queryDetailsParams.pageNum = 1;
			if (param.seriesType === 'line') {
				queryAlarmRatioDetail();
			} else {
				Object.assign(queryDetailsParams, queryParams, param.data[param.data.length - 1]);
				queryAlarmRatioDetail();
				queryNodeRatioMap(queryDetailsParams);
			}
		});
	});
}

//无数据为0
function dataNullFuc() {
	const option = {
		color: ['#b3b3b3'],
		legend: {
			show: false,
		},
		tooltip: {
			trigger: 'axis',
			showContent: true,
		},
		grid: { top: '65%' },
		series: [
			{
				type: 'pie',
				id: 'pie',
				radius: ['25%', '55%'],
				center: ['45%', '55%'],
				label: {
					show: false,
				},
				labelLine: {
					show: false,
				},
				data: [{ value: 100 }],
			},
		],
	};
	chart.alarmRatioMap.setOption(option);
}

//节点告警图
function queryNodeRatioMap(params: anyObj) {
	const titleName = params.alarmTypeName + '(' + dataQJStart.value + '-' + dataQJEnd.value + ')';
	nodeRatioMapLoading.value = true;
	getNodeRatioMap(params).then((res) => {
		if (res.code !== 0) {
			return;
		}
		//掉底处理2
		res.data[0].splice(res.data[0].length - 1, 1);
		const labelTime = res.data[0];
		dataSetOption(chart.nodeRatioMap, res.data, labelTime[labelTime.length - 1], titleName, labelTime);
		nodeRatioMapLoading.value = false;
	});
	chart.nodeRatioMap.off('click');
	chart.nodeRatioMap.on('click', function (param: anyObj) {
		toggleUi(false);
		queryDetailsParams.pageNum = 1;
		Object.assign(queryDetailsParams, queryParams, param.data[param.data.length - 1]);
		queryNodeRatioDetail();
	});
}

//告警占比饼图
function alarmRatioMapSetOption(myChart: any, data: any, setLabelTime: any) {
	myChart.clear();
	if (data === null || data.length <= 1) {
		noDataOption(myChart, {
			textStyle: { color: '#ffffff' },
		});
	} else {
		const option = {
			color: [
				'#e93074',
				'#1875f0',
				'#ff7d4f',
				'#bc66e7',
				'#feba71',
				'#00fefe',
				'#fe5578',
				'#1343d4',
				'#e0517f',
				'#8543f5',
				'#1cd1a1',
				'#1ec9d4',
				'#f8e2d7',
				'#4a98ff',
				'#ffffff',
			],
			legend: {
				type: 'scroll',
				orient: 'vertical',
				right: '15%',
				top: '20%',
				icon: 'circle',
				textStyle: {
					color: '#ffffffff',
					fontSize: 14,
					fontWeight: 'normal',
				},
			},

			tooltip: {
				trigger: 'axis',
				showContent: true,
			},
			dataset: {
				source: data,
			},
			grid: { top: '65%' },
			series: [
				{
					type: 'pie',
					id: 'pie',
					radius: ['25%', '55%'],
					center: ['45%', '55%'],
					label: {
						show: true,
						formatter: '{b}\n{da| {d}%}', //'{b}: {@' + setLabelTime + '} ({d}%)',
						rich: {
							d: {
								color: '#ffffff',
								lineHeight: 22,
								align: 'center',
								fontWeight: 'normal',
								fontSize: 14,
							},
						},
					},
					encode: {
						itemName: 'labelTime',
						value: setLabelTime,
						tooltip: setLabelTime,
					},
				},
			],
		};
		myChart.setOption(option, true);
	}
	myChart.resize();
}

// 线图事件
function dataSetOption(myChart: anyObj, data: any, setLabelTime: any[], titleName: string, labelTime: any) {
	if (data === null || data.length <= 1) {
		noDataOption(myChart, {
			textStyle: { color: '#ffffff' },
		});
	} else {
		let seriesLine = [];

		data.forEach((value: any, index: number) => {
			if (index > 0) {
				seriesLine.push({
					type: 'line',
					smooth: true,
					seriesLayoutBy: 'row',
					areaStyle: { opacity: 0.1 },
					symbol: false,
					symbolSize: 0,
				});
			}
		});

		seriesLine.push({
			type: 'pie',
			id: 'pie',
			radius: ['30%', '40%'],
			center: ['45%', '35%'],
			label: {
				show: true,
				formatter: '{b}\n{da| {d}%}', //'{b}: {@' + setLabelTime + '} ({d}%)',
				rich: {
					d: {
						color: '#ffffff',
						lineHeight: 22,
						align: 'center',
						fontWeight: 'normal',
						fontSize: 14,
					},
				},
			},
			encode: !dataNull.value
				? {
						itemName: 'labelTime',
						value: setLabelTime,
						tooltip: setLabelTime,
				  }
				: {
						itemName: 'labelTime',
				  },
		});

		const option = {
			color: [
				'#00fefe',
				'#1875f0',
				'#fe5578',
				'#1ec9d4',
				'#bc66e7',
				'#ff7d4f',
				'#1cd1a1',
				'#e93074',
				'#8543f5',
				'#feba71',
				'#1343d4',
				'#e0517f',
				'#f8e2d7',
				'#4a98ff',
				'#ffffff',
			],
			title: {
				text: titleName,
				textStyle: {
					color: '#ffffffff',
					fontWeight: 'bold',
					fontSize: 18,
				},
				top: 10,
				left: 40,
			},
			legend: {
				type: 'scroll',
				orient: 'vertical',
				right: '15%',
				top: '20%',
				icon: 'circle',
				textStyle: {
					color: '#ffffffff',
					fontSize: 14,
					fontWeight: 'normal',
				},
			},
			tooltip: {
				trigger: 'axis',
				formatter: function (params: any[]) {
					let result = '';
					let newresult = '';
					let newTime = '';
					if (params[0].data[0] === '00:00') {
						newTime = '00:00';
					} else {
						let leftTime = params[0].data[0].slice(0, 2);
						let rightTime = params[0].data[0].slice(3, 5);

						if (parseInt(rightTime) >= 10 || parseInt(rightTime) < 50) {
							newTime = leftTime + ':' + (parseInt(rightTime) + 10);
						} else if (rightTime === '50') {
							newTime = parseInt(leftTime) + 1 + ':00';
						}
					}
					if (newTime.slice(3, 5) === '60') {
						newTime = parseInt(newTime.slice(0, 2)) + 1 + ':00';
					}
					result += '<span style="font-size:14px"> ' + params[0].data[0] + '-' + newTime + '</span>' + '<br/>';

					let color = [
						'#00fefe',
						'#1875f0',
						'#fe5578',
						'#1ec9d4',
						'#bc66e7',
						'#ff7d4f',
						'#1cd1a1',
						'#e93074',
						'#8543f5',
						'#feba71',
						'#1343d4',
						'#e0517f',
						'#f8e2d7',
						'#4a98ff',
						'#ffffff',
					];

					for (let j = 1; j < params[0].dimensionNames.length; j++) {
						newresult +=
							'<div style="width: 10px; height: 10px; background-color: ' +
							color[j - 1] +
							'; border-radius: 50%;float:left;margin-top: 5px;margin-right:10px"></div>  ' +
							params[0].dimensionNames[j] +
							':  ' +
							params[0].data[j] +
							'</span><br/>';
					}

					return result + newresult;
				},
			},
			dataset: {
				source: data,
			},
			xAxis: {
				type: 'category',
				boundaryGap: false,
				axisLine: {
					show: true,
					lineStyle: {
						color: '#b9b9b9',
					},
				},
				axisLabel: {
					show: true,
					textStyle: {
						color: '#fff',
					},
				},
				axisTick: {
					show: false,
				},
			},
			yAxis: {
				gridIndex: 0,
				splitLine: {
					show: false,
				},
				axisLine: {
					show: true,
					lineStyle: {
						color: '#b9b9b9',
					},
				},
				axisLabel: {
					show: true,
					textStyle: {
						color: '#fff',
					},
				},
				axisTick: {
					show: false,
				},
			},
			grid: { top: '65%' },
			series: seriesLine,
		};
		myChart.setOption(option, true);

		chart.nodeRatioMap.off('updateAxisPointer');
		chart.nodeRatioMap.on('updateAxisPointer', function (event: anyObj) {
			// 防抖检查
			if (!checkDebounce(debounceObj)) {
				return;
			}

			if (event.axesInfo[0]) {
				if (event.axesInfo[0].value) {
					dataQJStart.value = labelTime[event.axesInfo[0].value + 1] ? labelTime[event.axesInfo[0].value + 1] : '';
					dataQJEnd.value = labelTime[event.axesInfo[0].value + 2] ? labelTime[event.axesInfo[0].value + 2] : '';
				}

				//时间处理
				if (dataQJEnd.value === '' || dataQJEnd.value === undefined || dataQJEnd.value === null) {
					if (dataQJStart.value === '00:00') {
						dataQJEnd.value = '00:10';
					} else {
						let leftTime = dataQJStart.value.slice(0, 2);
						let rightTime = dataQJStart.value.slice(3, 5);

						if (parseInt(rightTime) >= 10 || parseInt(rightTime) < 50) {
							dataQJEnd.value = leftTime + ':' + (parseInt(rightTime) + 10);
						} else if (rightTime === '50') {
							dataQJEnd.value = parseInt(leftTime) + 1 + ':00';
						}
					}
					if (dataQJEnd.value.slice(3, 5) === '60') {
						dataQJEnd.value = parseInt(dataQJEnd.value.slice(0, 2)) + 1 + ':00';
					}
				}

				const newdataQJStart = dataQJStart.value;
				const newdataQJEnd = dataQJEnd.value;

				if (AlarmRatioNum.value === 2) {
					if (data[1][event.axesInfo[0].value + 1] === 0) {
						dataNullFuc();
						dataNull.value = true;
						queryAlarmRatioDetail();
						queryNodeRatioDetail();
						queryNodeRatioMap(queryDetailsParams);
						//  titleName = titleName.split("(")[0];
						// chartCL(
						//   event,
						//   labelTime,
						//   titleName,
						//   newdataQJStart,
						//   newdataQJEnd
						// );
					} else {
						titleName = titleName.split('(')[0];
						chartCL(event, labelTime, titleName, newdataQJStart, newdataQJEnd);
					}
				} else {
					titleName = titleName.split('(')[0];
					chartCL(event, labelTime, titleName, newdataQJStart, newdataQJEnd);
				}
			}
		});
	}
	myChart.resize();
}

function chartCL(event: anyObj, labelTime: string, titleName: string, dataQJStart: string, dataQJEnd: string) {
	dataNull.value = false;
	alarmRatioMapSetOption(chart.alarmRatioMap, alarmRatioMapData.value, labelTime[labelTime.length - 1]);

	let xAxisInfo = event.axesInfo[0];
	if (xAxisInfo) {
		let dimension = xAxisInfo.value + 1;
		chart.nodeRatioMap.setOption({
			title: {
				text: titleName + '(' + dataQJStart + '-' + dataQJEnd + ')',
				textStyle: {
					color: '#ffffffff',
					fontWeight: 'bold',
					fontSize: 18,
				},
				top: 10,
				left: 40,
			},
			series: {
				type: 'pie',
				id: 'pie',
				radius: ['30%', '40%'],
				center: ['45%', '35%'],
				label: {
					formatter: '{b}\n{da| {d}%}', //'{b}: {@' + setLabelTime + '} ({d}%)',
					rich: {
						d: {
							color: '#ffffff',
							lineHeight: 22,
							align: 'center',
							fontWeight: 'normal',
							fontSize: 14,
						},
					},
				},
				encode: {
					value: dimension,
					tooltip: dimension,
				},
			},
		});
		chart.alarmRatioMap.setOption({
			legend: {
				show: true,
			},
			series: {
				type: 'pie',
				id: 'pie',
				radius: ['25%', '55%'],
				center: ['45%', '55%'],
				label: {
					show: true,
					formatter: '{b}\n{da| {d}%}', //'{b}: {@' + setLabelTime + '} ({d}%)',
					rich: {
						d: {
							color: '#ffffff',
							lineHeight: 22,
							align: 'center',
							fontWeight: 'normal',
							fontSize: 14,
						},
					},
				},
				labelLine: {
					show: true,
				},
				encode: {
					value: dimension,
					tooltip: dimension,
				},
			},
		});
	}
}

/**
 * 查询告警类型详情
 */
function queryAlarmRatioDetail() {
	if (dataNull.value) {
		tableData.data = [];
		alarmRatioDetailConfig.pagination!.pageNum = 0;
		return;
	}
	// alarmRatioDetailConfig.loading = true;
	getAlarmRatioDetail(queryDetailsParams).then((res: ApiResponse) => {
		// alarmRatioDetailConfig.loading = false;

		if (res.code === 0) {
			tableData.data = res.data.data;
			alarmRatioDetailConfig.pagination!.total = res.data.total;
		}
		loading.value = false;
	});
}
/**
 * 查询端告警详情
 */
function queryNodeRatioDetail() {
	if (dataNull.value) {
		nodeRatioDetailTableData.data = [];
		nodeRatioDetailConfig.pagination!.total = 0;

		return;
	}
	loading.value = true;
	// nodeRatioDetailConfig.loading = true;
	getNodeRatioDetail(queryDetailsParams).then((res: ApiResponse) => {
		// nodeRatioDetailConfig.loading = false;
		if (res.code === 0) {
			tableData.data = res.data.data;
			nodeRatioDetailConfig.pagination!.total = res.data.total;
		}

		loading.value = false;
	});
}
/**
 * 切换详情列表
 * @param param
 * @returns {boolean}
 */
function toggleUi(param: boolean) {
	if (param) {
		//告警占比详情查询列表是否展示
		ui.alarmRatioDetailShow = true;
		//告警网端详情列表是否展示

		ui.nodeRatioDetailShow = false;

		return false;
	}
	//告警占比详情查询列表是否展示
	ui.alarmRatioDetailShow = false;
	//告警网端详情列表是否展示

	ui.nodeRatioDetailShow = true;

	return false;
}

/**
 * 下载
 */
function download(type: string) {
	// debugger
	let table = tableType[type];
	if (type) {
		queryDetailsParams.exportType = type;
	}
	if (type === 'node') {
		if (nodeRatioDetailConfig.pagination!.total! === 0) {
			proxy?.$message.warning('暂无数据,无法下载！');
			return;
		}
	} else {
		if (alarmRatioDetailConfig.pagination!.total! === 0) {
			proxy?.$message.warning('暂无数据,无法下载！');
			return;
		}
	}
	downloadLoading.value = true;
	exportList(queryDetailsParams)
		.then((res) => {
			downloadLoading.value = false;
			downloadFromBlob(res, table);
		})
		.catch((reason) => {
			downloadLoading.value = false;
			proxy?.$message.warning('下载超时,请重新点击[下载]');
		});
}
function formatDate(value: any) {
	if (value === null || value === '') return '';
	let date = new Date(value);
	let year = date.getFullYear();
	let month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1;
	let day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
	let hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours();
	return year + '-' + month + '-' + day + ' ' + hours + ':' + '00' + ':' + '00';
}
</script>
<style scoped lang="scss">
.bg-chart {
	height: auto;
}
:deep(.el-table td) {
	/* border-bottom: 1px solid #56698d; */
}

:deep(.yd-card-header) {
	margin-bottom: 0;
}

:deep(.el-card__body) {
	// padding: 0;
}

:deep(.el-icon-download) {
	background: url('@/assets/icons/png/download.png') no-repeat;
	background-size: 18px;
	width: 20px;
}

:deep(.el-icon-download:before) {
	content: '替换';
	font-size: 16px;
	visibility: hidden;
}

.title-icon {
	content: '';
	background: #2beded;
	width: 10px;
	height: 9px;
	border-radius: 50%;
	margin-right: 2px;
	vertical-align: 110%;
	position: relative;
	display: block;
	left: 20px;
	top: 28px;
}
:deep(.yd-card-header-default) {
	padding-left: 0;
}
.style-split-yd-card {
	:deep(.el-card) {
		background-color: rgba(29, 39, 75, 0.31);
		border: unset;
		border-radius: 12px;
	}
	:deep(.el-card__header) {
		display: flex;
		justify-content: space-between;
		align-items: center;
		.icon-cls {
			width: 20px;
			height: 20px;
			color: #00ffff;
		}
	}
	:deep(.icon-cls) {
		width: 20px;
		height: 20px;
		color: #00ffff;
	}
}
</style>
